// 导入 useGLTF 钩子，它是来自 @react-three/drei 库，方便使用 GLTF 模型
import { useGLTF } from "@react-three/drei";
// 导入整个 three.js 库，它是 3D 渲染的核心库
import * as THREE from "three";
// 导入 React 库以及 React 的 useEffect 和 useRef 钩子
import React, { useEffect, useRef } from "react";
// 导入 useFrame 钩子，它来自 @react-three/fiber 库，用于在每一帧渲染时执行自定义逻辑
import { useFrame } from "@react-three/fiber";

// 定义一个名为 personIndex 的 React 函数组件，接收 src 和 num 作为 props
const personIndex = ({ src, num }) => {
  // 使用 useGLTF 钩子加载 src 指向的 GLTF 模型，得到 scene 和 animations
  // scene 是 GLTF 模型的场景对象，包含模型的网格、材质等
  // animations 是该模型的动画数组
  const { scene, animations } = useGLTF(src);
  // 创建一个 ref 引用，用于存储 THREE.Group 类型的对象，以便后续操作
  const ref = useRef<THREE.Group>();
  // 创建一个 ref 引用，用于存储 THREE.AnimationMixer 或 null，作为动画混合器
  const mixRef = useRef<THREE.AnimationMixer | null>(null);
  // 创建一个 ref 引用，用于存储 THREE.AnimationAction 或 null，作为动画动作
  const actionRef = useRef<THREE.AnimationAction | null>(null);

  // useEffect 钩子用于处理组件的副作用，在组件挂载和更新时执行
  useEffect(() => {
    // 检查 scene 和 animations 是否存在
    if (scene && animations) {
      // 创建一个新的 THREE.AnimationMixer 并将其存储在 mixRef 中
      // AnimationMixer 用于管理动画混合，可将多个动画组合在一起
      mixRef.current = new THREE.AnimationMixer(scene);
      // 从动画混合器中创建一个动画动作，使用 animations 数组中的第一个动画
      actionRef.current = mixRef.current.clipAction(animations[0]);
      // 播放动画动作
      actionRef.current.play();
    }
  }, [scene, animations, num]);

  // useFrame 钩子在每一帧渲染时调用回调函数
  useFrame((state, delta) => {
    // 检查 mixRef 是否存在
    if (mixRef.current) {
      // 更新动画混合器，delta 是帧之间的时间差，确保动画平滑过渡
      mixRef.current.update(delta);
    }
    // 检查 ref 是否存在
    if (ref.current) {
      // 设置 ref 所引用对象的位置，将其 y 坐标设为 -1
      ref.current.position.y = -0.7;
      // 将其 x 坐标设为 -0.3
      ref.current.position.x = 0;
    }
  });

  // 使用 primitive 元素将 scene 渲染到场景中，并将 ref 绑定到该元素
  return <primitive object={scene} ref={ref} />;
};

// 导出 personIndex 组件，使其可在其他文件中使用
export default personIndex;
